package com.supreme.nettyapp.generalclient.pingclient.service;

import com.supreme.nettyapp.generalclient.pingclient.handler.PingClientHandler;
import com.supreme.nettyapp.generalclient.pingclient.props.PingClientProps;
import com.supreme.nettyapp.generalclient.service.NettyChannelService;
import com.supreme.nettyapp.generalclient.service.NettyClientService;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class PingClientService implements NettyClientService, NettyChannelService {

    @Resource
    private PingClientProps pingClientProps;

    private Channel clientChannel;

    @Async(value = "nettyTask")
    @Override
    public void startNettyClient() {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast("encoder", MqttEncoder.INSTANCE);
                            pipeline.addLast("decoder", new MqttDecoder());
                            pipeline.addLast(new PingClientHandler());
                        }
                    });

            ChannelFuture channelFuture = bootstrap.connect(pingClientProps.getServerHost(), pingClientProps.getServerPort()).sync();
            clientChannel = channelFuture.channel();
            clientChannel.closeFuture().sync();
        } catch (InterruptedException e) {
            System.out.println("e.getMessage() = " + e.getMessage());
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }

    @Override
    public void startNettyClient(String host, int port) {

    }

    @Override
    public void destroyNettyClient() {

    }

    @Override
    public Channel getChannel() {
        return clientChannel;
    }

    @Override
    public void writeAndFlush(Object msg) {
        clientChannel.writeAndFlush(msg);
    }
}
